package com.java.stack;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

/**
 * （前缀表达式）波兰
 * （中缀表达式）
 * （后缀表达式）逆波兰
 * Reverse polish 逆波兰
 * 使用逆波兰完成一个简单的逆波兰计算器
 * @author 19252
 */
public class ReversePolishDemo {
    public static void main(String[] args) {
        // 先定义一个逆波兰表达式
        // (3+4)*5-6 => 3 4 + 5 * 6 -
        // 为了演示方便，逆波兰表达式的 数字和符号使用空格隔开
        // String expression = "3 4 + 5 * 6 -";
        // 多位数测试
        String expression = "30 4 + 5 * 6 -";
        ReversePolishDemo demo = new ReversePolishDemo();
        List<String> items = demo.getItemOfExpression(expression);
        for (String item : items) {
            System.out.println(item);
        }
        System.out.println(demo.calculate(items));
    }

    /**
     * 将数字和字符放入一个集合中，方便使用
     * @param expression 逆波兰表达式
     * @return 存放数字和字符的集合
     */
    public List<String> getItemOfExpression(String expression){
        String[] items = expression.split(" ");
        return new ArrayList<>(Arrays.asList(items));
    }

    /**
     * 对表达式进行计算
     * @param list 传入的表达式
     * @return 计算结果
     */
    public int calculate(List<String> list){
        Stack<String> stack = new Stack<>();
        int val1;
        int val2;
        int result = 0;
        for (String sub : list) {
            // sub 是数字的话，就入栈
            if (sub.matches("\\d+")) {
                stack.push(sub);
            } else {
                val1 = Integer.parseInt(stack.pop());
                val2 = Integer.parseInt(stack.pop());
                switch (sub) {
                    case "+":
                        result = val1 + val2;
                        break;
                    case "-":
                        result = val2 - val1;
                        break;
                    case "*":
                        result = val1 * val2;
                        break;
                    case "/":
                        result = val2 / val1;
                        break;
                    default:
                        break;
                }
                stack.push(String.valueOf(result));
            }
        }
        // 输出栈中最后的数据，这就是计算结果
        return Integer.parseInt(stack.pop());
    }
}
